# -*- coding: utf-8 -*-


from typing import Sequence, Callable, Any


def virtual(func):
    """
    Methods decorated by decorators support overloaded operations
    """

    return func


#


def async_call(func: Callable[[Sequence], Any], args: Sequence, *, call_handle: Callable[[Any], None]):
    """
    callback function
    ::param : func type function
    ::param : args func The type of argument required by the function,

        # case
        --------
        func(*args)
    ::param : call_handle callback function

    """

    res = func(*args)
    call_handle(res)


def type_property(name):
    """
    属性方法:
        # Example
        class A:
            def __init__(self, name=None):
                self._name = name
                self._age = 0
                self._heigh = 0
            @property
            def name(self):
                return self._name
            @property
            def age(self):
                return self._age
            @property
            def heigh(self):
                return self._heigh
        # Usage
        class A:
            _name = type_property("name")
            _age = type_property("age")
            _heigh = type_property("heigh")
            def __init__(self, name=None):
                self._name = name
                self._age = 0
                self._heigh = 0
    """

    cache_attr_name = "_#" + name

    @property
    def prop(self):
        getattr(self, cache_attr_name)

    @property
    def prop(self, value):
        setattr(self, cache_attr_name, value)

    return prop


class ToolsMixinsMeta(type):
    """ 
    Function: 
        Used to define tool classes, defined tools do not need to be instantiated,
        Utility classes can be implemented simply by integrating the abstract template, 
        objects that are not allowed to be instantiated directly by users,
        Add the class attribute "__abstract__" to the object with a value of True
    ----
    Example:
        class TemplateMixins(metaclass=TemplateMeta):
            __abstract__ = True
            ...

        class TemplateMixins1(TemplateMixins): 
            __abstract__ = True
            ...

        TemplateMixins1, TemplateMixins Can't be instantiated directly
    """

    def __call__(self, *args, **kwargs):
        if self.__dict__.get("__abstract__", False):
            error = self.__name__ + " Instantiation is not supported"
            raise AttributeError(error)
        return super().__call__(*args, **kwargs)


class ToolsMixinsStructer(metaclass=ToolsMixinsMeta):
    """ 
    It is also possible to integrate the class directly to avoid instantiation of utility classes,
    Also add the class attribute "__abstract__" to True
    """
    __abstract__ = True
    ...


def get_uuid():
    import uuid
    get_timestamp_uuid = uuid.uuid1()  # 根据 时间戳生成 uuid , 保证全球唯一
    # print("len---- ", len(str(get_timestamp_uuid.int)))
    return get_timestamp_uuid.int
    